﻿
namespace Cloudio.Web.UI.ToolboxItem
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Reflection;
    using System.Text.RegularExpressions;
    using System.Web.UI;
    using Cloudio.Core.WebFormsParser;
    using G = Gaia.WebWidgets;

    public class GaiaToolboxItem : GenericToolboxItem
    {
        private const string GaiaDirective = "<%@ Register assembly='Gaia.WebWidgets' namespace='Gaia.WebWidgets' tagprefix='gaia' %>";

        public string Name { get; set; }
        public object GaiaControl { get; set; }
        public Type Type { get; set; }
        public Image ToolboxImage { get; set; }

        public static Control GetGaiaControlForType(string typename)
        {
            var assembly = GetGaiaAssembly();

            foreach (var gaiaToolboxItem in GetGaiaToolboxItems())
                if (gaiaToolboxItem.Type == assembly.GetType(typename, false, true))
                    return gaiaToolboxItem.GaiaControl as Control;

            return null;
        }

        /// <summary>
        /// List all visible Gaia controls
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<GaiaToolboxItem> GetGaiaToolboxItems()
        {
            var assembly = GetGaiaAssembly();

            foreach (var type in assembly.GetTypes())
            {
                //only accept the following controls, which are tested
                if (!IsAcceptedGaiaControl(type)) continue;

                //we only need items that shows up in the toolbox, and they have this attribute
                var attributes =
                    type.GetCustomAttributes(typeof (System.ComponentModel.ToolboxItemAttribute), true) as
                    System.ComponentModel.ToolboxItemAttribute[];

                if (attributes == null || attributes.Length <= 0 || attributes[0].ToolboxItemType == null) continue;

                //grab the icon for the control
                var toolboxImage = new ToolboxBitmapAttribute(type).GetImage(type);

                yield return
                    new GaiaToolboxItem
                        {
                            GaiaControl = Activator.CreateInstance(type),
                            Type = type,
                            ToolboxImage = toolboxImage
                        };
            }
        }

        private static Assembly GetGaiaAssembly()
        {
            //just use our Label as example
            return Assembly.GetAssembly(typeof(G.Label));
        }

        private static bool IsAcceptedGaiaControl(Type type)
        {
            var acceptedTypes = new List<Type>
                                    {
                                        typeof (G.Label),
                                        typeof (G.Button),
                                        typeof (G.TextBox),
                                        typeof (G.Panel),
                                        typeof (G.CheckBox),
                                        typeof (G.Image),
                                        typeof (G.RadioButton)
                                    };

            return acceptedTypes.Contains(type);
        }

        public static IEnumerable<GenericToolboxItem> GetParsedControlsFromMarkup(TemplateControl page)
        {
            var retVal = "";

            //get markup
            foreach (var gaiaToolboxItem in GetGaiaToolboxItems())
                retVal += DesignSerializer.Serialize(gaiaToolboxItem.GaiaControl as Control);

            return GetParsedControlsFromMarkup(page, retVal);
        }

        private static IEnumerable<GenericToolboxItem> GetParsedControlsFromMarkup(TemplateControl page, string aspnetMarkup)
        {
            foreach (var control in Regex.Split(aspnetMarkup, "\r\n"))
            {
                var cntrl = page.ParseControl(GaiaDirective + control);
                if (cntrl == null) continue;

                var type = cntrl.GetType();

                yield return
                    new GenericToolboxItem
                    {
                        ToolBoxItemType = type,
                        ID = type.ToString()
                    };
            }
        }

        public static GenericToolboxItem GetParsedControl(TemplateControl page, string aspnetMarkup)
        {
            //we expect only one
            var parsedControlsFromMarkup = new List<GenericToolboxItem>(GetParsedControlsFromMarkup(page, aspnetMarkup));

            if (parsedControlsFromMarkup == null || parsedControlsFromMarkup.Count != 1)
                throw new Exception("Expected only one control back");

            return parsedControlsFromMarkup[0];
        }
    }
}